/**
 *  @file    BasicOperate.c
 *  @brief   顺序队列的基本操作实现（非循环队列）
 *  @details 演示：
 *           1) 队列初始化、入队、出队
 *           2) 队列判满 / 判空
 *           3) 获取队头、打印队列、求长度、清空
 *  @author  WangBlue (wangjiping596@gmail.com)
 *  @date    2025-07-29 10:27
 *  @version 1.0
 */

#include <stdio.h>
#include <stdbool.h>

// ------------------------- 宏定义与类型声明 -------------------------

typedef int EleType;            ///< 队列中元素的数据类型
#define MAX_SIZE 5              ///< 顺序队列的最大容量

/**
 * @brief 顺序队列结构体（非循环）
 */
typedef struct queue {
    EleType data[MAX_SIZE];     ///< 队列元素数组
    int rear, front;            ///< 队尾指针、队头指针（[front, rear) 区间存数据）
} queue;

// ------------------------- 队列初始化 -------------------------

/**
 * @brief 初始化顺序队列
 * @param q 指向队列结构体的指针
 * @note  front 与 rear 初始化为 0，表示队列为空
 */
void initQueue(queue *q) {
    q->front = 0;
    q->rear = 0;
    for (int i = 0; i < MAX_SIZE; i++) {
        q->data[i] = 0;
    }
}

// ------------------------- 判满判空 -------------------------

/**
 * @brief 判断队列是否已满
 * @param q 指向队列的指针
 * @retval true  队列已满
 * @retval false 队列未满
 */
bool isFill(queue *q) {
    return q->rear == MAX_SIZE;
}

/**
 * @brief 判断队列是否为空
 * @param q 指向队列的指针
 * @retval true  队列为空
 * @retval false 队列非空
 */
bool isEmpty(queue *q) {
    return q->front == q->rear;
}

// ------------------------- 入队操作 -------------------------

/**
 * @brief 将元素入队（添加至队尾）
 * @param q     指向队列的指针
 * @param value 要入队的元素值
 * @note 若队列已满，函数无操作
 */
void inQueue(queue *q, EleType value) {
    if (isFill(q)) return;
    q->data[q->rear] = value;
    q->rear++;
}

// ------------------------- 出队操作 -------------------------

/**
 * @brief 将队头元素出队（删除）
 * @param q     指向队列的指针
 * @param value 用于保存出队元素的变量地址
 * @note 若队列为空，函数无操作
 */
void deQueue(queue *q, EleType *value) {
    if (isEmpty(q)) return;
    *value = q->data[q->front];
    q->front++;
}

// ------------------------- 查看队头 -------------------------

/**
 * @brief 查看队头元素（不出队）
 * @param q     指向队列的指针
 * @param value 用于保存队头值的变量地址
 * @note 若队列为空，函数无操作
 */
void peek(queue *q, EleType *value) {
    if (isEmpty(q)) return;
    *value = q->data[q->front];
}

// ------------------------- 打印队列 -------------------------

/**
 * @brief 打印当前队列中所有元素（从 front 到 rear）
 * @param q 指向队列的指针
 */
void printQueue(queue *q) {
    if (isEmpty(q)) return;
    for (int i = q->front; i < q->rear; i++) {
        printf("value is %d\n", q->data[i]);
    }
    printf("\n");
}

// ------------------------- 获取队列长度 -------------------------

/**
 * @brief 获取队列当前长度
 * @param q 指向队列的指针
 * @return 当前队列中元素的个数
 */
int getLength(queue *q) {
    return q->rear - q->front;
}

// ------------------------- 清空队列 -------------------------

/**
 * @brief 清空队列，重置 front 和 rear 指针
 * @param q 指向队列的指针
 */
void clearQueue(queue *q) {
    q->rear = 0;
    q->front = 0;
    for (int i = 0; i < MAX_SIZE; i++) {
        q->data[i] = 0;
    }
}

// ------------------------- 主函数测试 -------------------------

/**
 * @brief 测试顺序队列的基本操作
 */
int main() {
    queue q;
    initQueue(&q);              // 初始化队列

    inQueue(&q, 1);
    inQueue(&q, 2);

    /* 查看队头元素 */
    int value;
    peek(&q, &value);
    printf("top is value %d\n", value);


    // // 元素出队
    // EleType deQueueValue;
    // deQueue(&q, &deQueueValue);
    //
    // // 打印元素
    // printQueue(&q);





    /* 查看队头元素 */
    // int value;
    // peek(&q, &value);
    // printf("top is value %d\n", value);

    // /* 清空队列并打印 */
    // clearQueue(&q);
    // printQueue(&q);             // 不输出任何内容（队空）
}
